package com.star.io.nio;

import ch.qos.logback.core.encoder.EchoEncoder;
import lombok.extern.slf4j.Slf4j;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;

import static com.star.io.nio.ByteBufferUtil.debugAll;


/**
 * @Description ByteBuffer测试类
 * @Author powder
 * @Date 2024/10/24
 * @Version 1.0
 **/
@Slf4j
public class ByteBufferTest {
    public static void main(String[] args) {
        // short a = 0x2211;
        // System.out.println(a & 0xff);
        // baseReadTest();
         decodeTest();
         log.info("日志测试");
    }

    private static void decodeTest() {
        try (FileChannel channel = new RandomAccessFile("file\\packet.txt", "rw").getChannel()) {
            ByteBuffer buffer = ByteBuffer.allocate(32);
            // 写入测试粘包的数据
            buffer.put("Hello World!\nHello China!\nHe".getBytes());
            decode(buffer);
            buffer.put("llo powder!\n".getBytes());
            decode(buffer);
            while (buffer.hasRemaining()) {
                channel.write(buffer);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void decode(ByteBuffer source) {
        source.flip();
        for (int i = 0; i < source.limit(); i++) {
            // buffer.get(i) 不会移动position指针 找到一条完整消息
            if ('\n' == source.get(i)) {
                int length = i - source.position() + 1;
                // 把这条完整消息存入新的Bytebuffer
                ByteBuffer target = ByteBuffer.allocate(length);
                // 从source读 向target写
                for (int j = 0; j < length; j++) {
                    target.put(source.get());
                }
//                byte[] res = target.array();
//                System.out.println(new String(res, StandardCharsets.UTF_8));
                debugAll(target);
            }
        }
        // 剩余字符交给下一次处理
        source.compact();
    }

    private static void baseReadTest() {
        // channel比stream更底层
        // FileInputStream: 只能写出 -> 对应channel.read() Bytebuffer.put()
        try (FileChannel channel = new FileInputStream("file\\data.txt").getChannel()) {
            ByteBuffer buffer = ByteBuffer.allocate(10);
            // src.put(new byte[]{0x61, 0x62, 0x63, 0x64, 0x65});
            // 利用buffer循环读取
            while (true) {
                // 可以理解为channel.readTo(ByteBuffer src) -> 操作对象为src，所以是读入src buffer
                channel.read(buffer);
                // 切换为读模式
                buffer.flip();
                // 一次读的过程
                if (!buffer.hasRemaining()) break;
                while (buffer.hasRemaining()) {
                    // buffer.get() 会移动position指针
                    System.out.println((char) buffer.get());
                }
                // 切换成写模式，清空缓冲区
                buffer.clear();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
